/*
 * Copyright 2008 Carnegie Mellon University
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package edu.cmu.lti.sepia.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;

import edu.cmu.lti.sepia.data.db.FilePermissisonDAO;
import edu.cmu.lti.sepia.data.db.SQL;
import edu.cmu.lti.sepia.data.db.UploadedFileDAO;
import edu.cmu.lti.sepia.data.db.UserDAO;
import edu.cmu.lti.sepia.infra.system.model.FilePermission;
import edu.cmu.lti.sepia.infra.system.model.UploadedFile;
import edu.cmu.lti.sepia.infra.system.model.User;
import edu.cmu.lti.sepia.util.ServletUtil;

public class Downloader extends HttpServlet {

  private static final long serialVersionUID = 1L;

  public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
  
    ServletUtil s = new ServletUtil( request );
    int userId = s.readInt("userId", -1);
    int taskId = s.readInt("taskId", -1);
    
    Commons.printHeader(request, response, "Downloader", 2);
    
    SQL sql = new SQL();
    try {
      String list = listMySubmission( sql, userId, taskId );
      String button = (list.indexOf("<table")!=-1?getButton():"");
      response.getOutputStream().println("<br><!--<h4>Files downloadable "+request.getRemoteUser()+"</h4>-->\n"+
       "<form action=\""+request.getContextPath()+"/io/file_fetcher.html\" method=\"POST\" name=\"dl_form\"" +
      " onsubmit=\"if(!verifyChecked('fileId')){alert('Please select the files to download');return false;};\">\n"+
      list+
      button+
      "</form>\n");
    } catch (Exception e) {
      throw new IOException(e);
    } finally {
      try {
        sql.close();
      } catch (Exception e){e.printStackTrace();}
    }
  
    Commons.printFooter(request, response);
  }

  public static String listMySubmission(SQL sql, int userId, int taskId) 
  throws Exception {

    StringBuilder sb = new StringBuilder();
    //file id to file map
    Map<Integer,UploadedFile> fileMap = new LinkedHashMap<Integer,UploadedFile>();
    List<UploadedFile> myfilesWithTaskId = UploadedFileDAO.findByUserAndTaskId(sql, userId, taskId);
    List<UploadedFile> myfilesWithoutTaskId = UploadedFileDAO.findByUserAndTaskId(sql, userId, 0);
    List<UploadedFile> myFiles = new ArrayList<UploadedFile>();
    myFiles.addAll(myfilesWithTaskId);
    myFiles.addAll(myfilesWithoutTaskId);
    
    List<FilePermission> permissions = FilePermissisonDAO.findByTaskId(sql, taskId);
    for (FilePermission fp : permissions) {
      int permittedFileId = fp.getFileId();
      if (fileMap.containsKey(permittedFileId)) continue;
      UploadedFile sharedFiles = UploadedFileDAO.findById(sql, permittedFileId);
      fileMap.put(fp.getFileId(), sharedFiles);
    }
    for (UploadedFile f : myFiles) {
      int myFileId = f.getFileId();
      if (fileMap.containsKey(myFileId)) continue;
      fileMap.put(myFileId, f);
    }
    
    Map<Integer,User> users = UserDAO.getUsersInMap(sql);
    List<UploadedFile> files = new ArrayList<UploadedFile>(fileMap.values());
    Collections.sort( files, new Comparator<UploadedFile>() {
      public int compare(UploadedFile f1, UploadedFile f2) {
        return f1.getDate().compareTo(f2.getDate());
      }
    });
    
    if (fileMap.size()==0) {
      sb.append("No files available for you yet.\n");
    } else {
      sb.append("Here are files you can download, including files you uploaded.<br><br>\n");
      sb.append("Select files and click on download button.<br><br>\n");
     
      sb.append("<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"datatable\">\n");
      sb.append("<thead>"+getTableHeader()+"</thead>\n");
      sb.append("<tbody>\n");
      
      for (int i=0;i<files.size(); i++) {
        UploadedFile file = files.get(i);
        String td1 = "<td><label for=\"file"+file.getFileId()+"\">";
        String td2 = "</label></td>\n";
        sb.append( "<tr class=\""+(i%2==1?"odd":"even")+"\">\n" );
        sb.append( td1+"<input type=\"checkbox\" name=\"fileId\" class=\"fileId\" value=\""+file.getFileId()+"\" id=\"file"+file.getFileId()+"\">"+td2 );
        sb.append( td1+"<nobr>"+file.getType()+"</nobr>"+td2 );
        sb.append( td1+"<nobr>"+file.getFileName()+"</nobr>"+td2 );
        sb.append( td1+file.getDescription()+td2 );
        sb.append( td1+"<nobr>"+file.getDate()+"</nobr>"+td2 );
        sb.append( td1+"<nobr>"+FileUtils.byteCountToDisplaySize(file.getSize())+"</nobr>"+td2 );
        sb.append( td1+"<nobr>"+users.get(file.getUserId()).getUserName()+"</nobr>"+td2 );
        sb.append( "</tr>\n" );
      }
      sb.append("</tbody>\n");
      //sb.append("<tfoot>"+getTableHeader()+"</tfoot>");
      sb.append("</table>\n");
    }
    return sb.toString();
  }
  
  public static String getButton() {
    return "<br><br>"+getCheckAllButton()+"<br>"+
    "<input type=\"submit\" value=\"Download Selected Item\">\n";
  }
  
  public static String getCheckAllButton() {
    return "Select: <a href=\"javascript:checkAll('fileId');\">All</a>&nbsp;&nbsp;\n"+
    "<a href=\"javascript:uncheckAll('fileId')\">None</a><br>\n";
  }
  
  private static String getTableHeader() {
    StringBuilder sb = new StringBuilder();
    sb.append("<tr>\n");
    sb.append("<th>&nbsp;</th>\n");
    sb.append("<th>Type</th>\n");
    sb.append("<th>Name</th>\n");
    sb.append("<th>Description</th>\n");
    sb.append("<th>Date modified</th>\n");
    sb.append("<th>Size</th>\n");
    sb.append("<th>File owner</th>\n");
    sb.append("</tr>\n");
    return sb.toString();
  }
  
}
